﻿using System;
using biz.ritter.javapi.lang;
using biz.ritter.javapi.lang.reflect;
using Nofs.Net.nofs.metadata.interfaces;

namespace Nofs.Net.nofs.metadata.XMLDriver
{

    public sealed class XMLMethodFilter : IMethodFilter
    {

        private IAttributeAccessor _attributeAccessor;
        private XMLFileSystem _fs;

        public XMLMethodFilter(XMLFileSystem xmlFileSystem, IAttributeAccessor accessor)
        {
            _fs = xmlFileSystem;
            _attributeAccessor = accessor;
        }

        //@SuppressWarnings("unchecked")
        private static String GetNameFromClass(Class cls)
        {
            //return cls.getPackage().getName() + "." + cls.getSimpleName();
            return cls.getName();
        }

        private static bool CompareMethodNames(Method method, String name)
        {
            if (name != null)
            {
                String methodName = method.getName();
                if (methodName.compareTo(name) == 0)
                {
                    return true;
                }
                else if (methodName.startsWith("get") || methodName.startsWith("set"))
                {
                    if (methodName.substring(3).compareTo(name) == 0)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private bool IsContainerOrNameSetterGetter(Object parent, Method method) //throws Exception 
        {
            XMLDomainObject domainObj = _fs.GetDomainObjectByName(GetNameFromClass(parent.getClass()));
            return
                CompareMethodNames(method, domainObj.NeedsContainerManagerMethod()) ||
                CompareMethodNames(method, domainObj.NeedsContainerMethod()) ||
                CompareMethodNames(method, domainObj.ProvidesNameMethod());
        }

        public bool UseMethod(Object parent, Method method) //throws Exception 
        {
            bool use = !(
                _attributeAccessor.isDomainObject(method) ||
                _attributeAccessor.isFolderObject(method) ||
                _attributeAccessor.isExecutable(method) ||
                IsContainerOrNameSetterGetter(parent, method)
            );
            if (!use)
            {
                Console.Write("excluding: " + GetNameFromClass(parent.getClass()) + "." + method.getName());
                if (IsContainerOrNameSetterGetter(parent, method))
                {
                    Console.Write(" (container / name getter-setter)");
                }
                if (_attributeAccessor.isDomainObject(method))
                {
                    Console.Write(" isDomainObject");
                }
                if (_attributeAccessor.isFolderObject(method))
                {
                    Console.Write(" isFolderObject");
                }
                if (_attributeAccessor.isExecutable(method))
                {
                    Console.Write(" isExecutable");
                }
                Console.WriteLine();
            }
            return use;
        }

    }
}
